//! 控制台输出模块
//! 提供基本的字符输出和格式化输出功能

use core::fmt;

// 加载架构特定的实现
cfg_if::cfg_if! {
    if #[cfg(target_arch = "loongarch64")] {
        mod loongarch64;
        pub use loongarch64::*;
    } else if #[cfg(target_arch = "aarch64")] {
        mod aarch64;
    } else if #[cfg(target_arch = "riscv64")] {
        mod riscv64;
        pub use riscv64::*;
    } else if #[cfg(target_arch = "x86_64")] {
        mod x86_64;
    } else {
        compile_error!("unsupported architecture!");
    }
}

/// 控制台结构体，用于输出字符到控制台
pub struct Console;

impl Console {
    /// 向控制台输出一个字符串
    pub fn puts(s: &str) {
        for c in s.bytes() {
            Self::putchar(c);
        }
    }
}

/// 为Console实现Write trait
impl fmt::Write for Console {
    fn write_str(&mut self, s: &str) -> fmt::Result {
        Console::puts(s);
        Ok(())
    }
}


#[macro_export]
macro_rules! println {
    () => ($crate::print!("\n"));
    ($($arg:tt)*) => ({
        use core::fmt::Write;
        let _ = write!(&mut $crate::console::Console, $($arg)*);
        $crate::console::Console::puts("\n");
    })
}

#[macro_export]
macro_rules! print {
    ($($arg:tt)*) => ({
        use core::fmt::Write;
        let _ = write!(&mut $crate::console::Console, $($arg)*);
    })
}

/// 输出INFO级别日志，带有绿色[INFO]前缀，整个消息都是绿色
#[macro_export]
macro_rules! INFO {
    ($($arg:tt)*) => ({
        use core::fmt::Write;
        let _ = write!(&mut $crate::console::Console, "\x1b[32m[INFO] ");
        let _ = write!(&mut $crate::console::Console, $($arg)*);
        $crate::console::Console::puts("\x1b[0m\n");
    })
}

/// 输出WARN级别日志，带有黄色[WARN]前缀，整个消息都是黄色
#[macro_export]
macro_rules! WARN {
    ($($arg:tt)*) => ({
        use core::fmt::Write;
        let _ = write!(&mut $crate::console::Console, "\x1b[33m[WARN] ");
        let _ = write!(&mut $crate::console::Console, $($arg)*);
        $crate::console::Console::puts("\x1b[0m\n");
    })
}

/// 输出ERROR级别日志，带有红色[ERROR]前缀，整个消息都是红色
#[macro_export]
macro_rules! ERROR {
    ($($arg:tt)*) => ({
        use core::fmt::Write;
        let _ = write!(&mut $crate::console::Console, "\x1b[31m[ERROR] ");
        let _ = write!(&mut $crate::console::Console, $($arg)*);
        $crate::console::Console::puts("\x1b[0m\n");
    })
}